﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client.Receiving;
using MQTTnet.Server;

namespace Server.Library.MQTT
{
    public class MQTTServerEntity
    {
        public delegate void ClientOperation(string id);

        public delegate void ClientMessage(string id, string topic, string msg);

        public event ClientOperation ClientConnected;
        public event ClientOperation ClientDisConnected;
        public event ClientMessage ClientMessageReceived;

        // mqtt服务器
        // 启动服务器
        // 停止服务器
        // 日志记录

        private string _ip = null;
        private int _port = -1;
        private bool _serverStatus = false;

        /// <summary>
        /// 默认端口
        /// </summary>
        public const int DefaultPort = 1883;

        /// <summary>
        /// ip地址
        /// </summary>
        public string Ip => _ip;

        /// <summary>
        /// 端口号
        /// </summary>
        public int Port => _port;

        /// <summary>
        /// 服务器运行状态
        /// </summary>
        public bool ServerStatus => _serverStatus;

        private IMqttServer _mqttServer;
        private MqttServerOptionsBuilder _optionsBuilder;

        protected MQTTServerEntity() { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <param name="port">端口号</param>
        public MQTTServerEntity(string ip, int port)
            : this()
        {
            _ip = ip;
            _port = port;

            _optionsBuilder = new MqttServerOptionsBuilder();
            _optionsBuilder.WithDefaultEndpointBoundIPAddress(IPAddress.Parse(ip)).WithDefaultEndpointPort(_port);
            _mqttServer = new MqttFactory().CreateMqttServer();

            // 客户端连接的时候
            _mqttServer.UseClientConnectedHandler(han =>
            {
                ClientConnected?.Invoke(han.ClientId);
            });

            // 客户端断开连接时
            _mqttServer.UseClientDisconnectedHandler(han =>
            {
                ClientDisConnected?.Invoke(han.ClientId);
            });

            // 收到客户端消息时
            _mqttServer.UseApplicationMessageReceivedHandler(han =>
            {
                // 获取客户端id
                // 获取客户端消息
                string id = han.ClientId;
                var msg = han.ApplicationMessage;
                if (msg.Payload != null)
                {
                    var strMsg = Encoding.UTF8.GetString(msg.Payload);
                    ClientMessageReceived?.Invoke(id,msg.Topic, strMsg);
                }
            });

        }

        // 客户端连接时

        // 客户端断开连接时

        // 客户端推送数据时


        /// <summary>
        /// 启动
        /// </summary>
        public void Start()
        {
            if (_serverStatus)
            {
                return;
            }
            new Thread(() =>
            {
                _mqttServer.StartAsync(_optionsBuilder.Build());
            }).Start();
            _serverStatus = true;
        }


        /// <summary>
        /// 发布主题
        /// </summary>
        /// <param name="topic">主题</param>
        /// <param name="context">内容</param>
        public void Publish(string topic, string context)
        {
            MqttApplicationMessage msg = new MqttApplicationMessage();
            msg.Topic = topic;
            msg.Payload = Encoding.UTF8.GetBytes(context);
            _mqttServer.PublishAsync(msg, CancellationToken.None);
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Cancel()
        {
            if (!_serverStatus)
            {
                return;
            }
            _mqttServer.StopAsync();
            _serverStatus = false;
        }
    }
}
